package com.alex.core.sms;


import cn.hutool.core.date.DateTime;
import com.ddcx.config.CoreProperties;
import com.ddcx.date.DateUtils;
import com.ddcx.redis.RedisClientUtil;
import com.ddcx.security.md5.MD5Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.*;

@Component
@Slf4j
public class SendSMSUtils {
    /**
     * 云片短信配置
     */
    //智能匹配模板发送接口的http地址
    private static String URI_SEND_SMS =
            "https://sms.yunpian.com/v2/sms/single_send.json";

    //模板发送接口的http地址
    private static String URI_TPL_SEND_SMS =
            "https://sms.yunpian.com/v2/sms/tpl_single_send.json";

    //发送语音验证码接口的http地址
    private static String URI_SEND_VOICE =
            "https://voice.yunpian.com/v2/voice/send.json";

    //编码格式。发送编码格式统一用UTF-8
    private static String ENCODING = "UTF-8";

    private static String apikey = "748bc42d9fcc673dbfbfed3395c34798";

    /**
     * 信使短信配置
     */
    private static String userid = "188";
    private static String userName = "hzcc";
    private static String passWord = "Changchonghz";
    private static String xsUrl = "http://139.196.253.160:8088/v2sms.aspx";

    private static String contant = "【杭州畅充科技】您的验证码是110110。如非本人操作，请忽略本短信";

    @Autowired
    private RedisClientUtil redisClientUtil;

    @Autowired
    private HttpClient httpClient;

    @Autowired
    private CoreProperties coreProperties;
    /**
     * 发送验证码
     *
     * @param mobile
     * @param
     * @return
     */
    public  Boolean sendMessageCode(String mobile, String id) {
        Boolean result = false;
        String code = randomNumber();
        try {
            String format = String.format(coreProperties.getSmsMessageCode(), code);
            result = this.sendSms(apikey,format,mobile);
            if (result) {
                // TODO: 2019/10/18  下面注释的方法为redis的存储方法
                redisClientUtil.set(id, code,300L);
                log.info("短信发送成功后台用户id为: "+id+"_手机号为: "+mobile);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("短信发送失败,后台用户id为: "+id+"_手机号为: "+mobile);
        }
        return result;
    }

    /**
     * 获取进入发送用户注册手机验证码次数
     * @param mobile
     * @return
     */
    public int registerMobileCodeCountForToday(String mobile)
    {
        String countKey = String.format("user.reg.mobile.code.count.%s", mobile);
        String codeKey = String.format("user.reg.mobile.code.%s", mobile);
        Integer count = redisClientUtil.getByKey(countKey);
        if(count == null)
            return 0;
        return count.intValue();
    }


    /**
     * 发送用户手机注册验证码，限制：一个手机号每天只能发送6条短信
     *
     * @param mobile
     * @param
     * @return
     */
    public  Boolean sendRegisterMobileCode(String mobile) {
        Boolean result = false;
        String countKey = String.format("user.reg.mobile.code.count.%s", mobile);
        String codeKey = String.format("user.reg.mobile.code.%s", mobile);
        Integer count = redisClientUtil.getByKey(countKey);
        if(count == null){
            Calendar endTime =  Calendar.getInstance();
            endTime.add(Calendar.DAY_OF_YEAR, 1);
            endTime.set(Calendar.HOUR, 0);
            endTime.set(Calendar.MINUTE, 0);
            endTime.set(Calendar.SECOND, 0);
            Long expireMillis = DateTime.now().getTime() - endTime.getTime().getTime();
            redisClientUtil.set(countKey, "1", expireMillis);
        }
        redisClientUtil.incr(countKey);

        String code = randomNumber();
        try {
            String format = String.format(coreProperties.getSmsMessageCode(), code);
            result = this.sendSms(codeKey, format, mobile);
            if (result) {
                redisClientUtil.set(codeKey, code,300L);
                log.info("短信发送成功后台用户id为: " + codeKey + "_手机号为: "+mobile);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("短信发送失败,后台用户id为: " + codeKey + "_手机号为: "+mobile);
        }
        return result;
    }

    /**
     * 发送账号信息修改后的短信
     * @param mobile
     * @return
     */
    public  Boolean sendUpdateAccount(String mobile) {
        Boolean bo = false;
        try {
            Boolean result = this.sendSms(apikey,coreProperties.getSmsUpdateAccountInfo(),mobile);
            if (result) {
                bo = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bo;
    }
    /**
     * 发送收款账号信息修改后的短信
     *
     * @param mobile
     * @return
     */
    public  Boolean sendUpdatePayInfo(String mobile) {
        Boolean bo = false;
        try {
            Boolean result = this.sendSms(apikey,coreProperties.getSmsUpdatePayInfo(),mobile);
            if (result) {
                bo = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bo;
    }
    /**
     * 生成随机六位数
     *
     * @return
     */
    private static String randomNumber() {
        int number= ((int)((Math.random()*9+1)*100000));
        return String.valueOf(number);
    }

    /**
     * 通过模板发送短信(不推荐)
     *
     * @param apikey    apikey
     * @param tpl_id    　模板id
     * @param tpl_value 　模板变量值
     * @param mobile    　接受的手机号
     * @return json格式字符串
     * @throws IOException
     */

    public Boolean tplSendSms(String apikey, long tpl_id, String tpl_value,
                                    String mobile) throws IOException {
        Map < String, String > params = new HashMap < String, String > ();
        params.put("apikey", apikey);
        params.put("tpl_id", String.valueOf(tpl_id));
        params.put("tpl_value", tpl_value);
        params.put("mobile", mobile);
        return post(URI_TPL_SEND_SMS, params);
    }

    /**
     * 智能匹配模板接口发短信
     *
     * @param apikey apikey
     * @param text   　短信内容
     * @param mobile 　接受的手机号
     * @return json格式字符串
     * @throws IOException
     */
    public  Boolean sendSms(String apikey, String text,
                                 String mobile) throws IOException {

        Map < String, String > params = new HashMap < String, String > ();
        params.put("apikey", apikey);
        params.put("text", text);
        params.put("mobile", mobile);
        return post(URI_SEND_SMS, params);
    }

    public  Boolean post(String url, Map < String, String > paramsMap) {
        Boolean boo = false;
        HttpResponse response = null;
        HttpPost method = new HttpPost(url);
        try {
            if (paramsMap != null) {
                List<NameValuePair> paramList = new ArrayList<NameValuePair>();
                for (Map.Entry < String, String > param: paramsMap.entrySet()) {
                    NameValuePair pair = new BasicNameValuePair(param.getKey(),
                            param.getValue());
                    paramList.add(pair);
                }
                method.setEntity(new UrlEncodedFormEntity(paramList,
                        ENCODING));
            }
            response = httpClient.execute(method);
            StatusLine status = response.getStatusLine();
            if(200 == status.getStatusCode()){
                boo = true;
            }else{
                log.error("平台返回信息: "+response.toString());
            }
            return boo;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("平台返回信息: "+response.toString());
        } finally {
            try {
                method.releaseConnection();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return boo;
    }

    /// <summary>
    /// 发送短信
    /// </summary>
    /// <param name="mobile">手机号</param>
    /// <param name="content">内容</param>
    /// <returns></returns>
    public  Boolean sendXsMessageCode(String mobile,String content) {
        Boolean bo = false;
        String timestamp = DateUtils.format(new Date(),"yyyyMMddHHmmss");
        String sign = this.xsSign(timestamp);
        HttpResponse response = null;
        HttpPost method = new HttpPost(xsUrl);
        try {
            List<NameValuePair> paramList = new ArrayList<NameValuePair>();
            NameValuePair userIdPair= new BasicNameValuePair("userid",userid);
            NameValuePair timestampPair = new BasicNameValuePair("timestamp",timestamp);
            NameValuePair signPair = new BasicNameValuePair("sign",sign);
            NameValuePair mobilePair = new BasicNameValuePair("mobile",mobile);
            NameValuePair contentPair = new BasicNameValuePair("content", content);
            NameValuePair sentTime = new BasicNameValuePair("sendTime",null);
            NameValuePair extno = new BasicNameValuePair("extno",null);
            NameValuePair action = new BasicNameValuePair("action","send");
            paramList.add(userIdPair);
            paramList.add(timestampPair);
            paramList.add(signPair);
            paramList.add(mobilePair);
            paramList.add(contentPair);
            paramList.add(sentTime);
            paramList.add(extno);
            paramList.add(action);
            method.setEntity(new UrlEncodedFormEntity(paramList,
                    ENCODING));
            response = httpClient.execute(method);
            StatusLine status = response.getStatusLine();
            if(200 == status.getStatusCode()){
                bo = true;
            }else{
                log.error("平台返回信息: "+response.toString());
            }
            return bo;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("平台返回信息: "+response.toString());
        } finally {
            try {
                method.releaseConnection();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //post传参数  
//        String str = "userid=" + userid + "&timestamp=" + timestamp + "&sign=" + sign + "&mobile=" + mobile + "&content=" + HttpUtility.UrlEncode(content, "UTF-8") + "&sendTime=&extno=&action=send";
        return bo;
    }

    
    //信使短信签名
    private  String xsSign(String timestamp) {
        String strSign = userName + passWord + timestamp;
        return MD5Utils.getMD5(strSign).toLowerCase();
    }

}
